package it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreUtil;

import it.univaq.mancoosi.injectors.systemconfiguration.managers.BootManager;
import it.univaq.mancoosi.injectors.systemconfiguration.managers.ConfigurationManager;
import it.univaq.mancoosi.injectors.systemconfiguration.utils.ProcessCommand;
import it.univaq.mancoosi.mancoosimm.Alternative;
import it.univaq.mancoosi.mancoosimm.BootScript;
import it.univaq.mancoosi.mancoosimm.File;
import it.univaq.mancoosi.mancoosimm.InstalledPackage;
import it.univaq.mancoosi.mancoosimm.Rule;
import it.univaq.mancoosi.mancoosimm.Service;

public class UbuntuBootManager extends BootManager {

	public UbuntuBootManager(){
		super();
	}

	public static BootManager getInstance() {
		if (INSTANCE == null)
			INSTANCE = new UbuntuBootManager();
		return INSTANCE;
	}

	public void createServicesFromSystem() {
		syncMap();
		if(UbuntuEnvironmentManager.getInstance().getEnvironment().getBoot() != null){
			getBoot().getServices().addAll(UbuntuEnvironmentManager.getInstance().getEnvironment().getBoot().getServices());
		}
		Service newService;
		String line;

		try {
			String[] cmd = {"/bin/sh","-c","ls --time-style=long-iso /etc/init.d"};
//			String[] cmd = {"/bin/sh","-c","ls --time-style=long-iso /home/martina/prova/cartella"};
			BufferedReader input = ProcessCommand.getInstance().getResult(cmd);		

			while ((line = input.readLine()) != null) {				
				
				java.io.File serviceFile = new java.io.File("/etc/init.d/" + line);
//				java.io.File scriptFile = new java.io.File("/home/martina/prova/cartella/" + line);
				
				if(serviceFile.exists() && !line.equals("README")){
					UbuntuFileSystemManager.getInstance().createFile("/etc/init.d/" + line);
//					UbuntuFileSystemManager.getInstance().createFile("/home/martina/prova/cartella/" + line);
				}
					if  (!line.equals("README")) {
						if (!exists(serviceFile.getName())) {
						newService = factory.createService();
						newService.setName(line);
						getBoot().getServices().add(newService);
						newService.setBoot(getBoot());
						this.serviceMap.put(newService.getName(), newService);
						}
					}
			}
			setServicesAttributes();
			getBoot().setEnv(UbuntuEnvironmentManager.getInstance().getEnvironment());

			input.close();

			} catch (Exception err) {
				err.printStackTrace();
			}	
		}
	
	protected void setServicesAttributes(){
		String line = new String();
		Iterator <Service> serviceIter = serviceMap.values().iterator();
		
		while(serviceIter.hasNext()){
			
			Service service = serviceIter.next();
			String serviceName = service.getName();
			
			//set running services
			try {
				String[] cmd = {"/bin/sh","-c","service "+serviceName+" status"};
				
				BufferedReader input = ProcessCommand.getInstance().getResult(cmd);

//				Process p = Runtime.getRuntime().exec(cmd);
//				BufferedReader input =
//					new BufferedReader
//					(new InputStreamReader(p.getInputStream()));

				line = input.readLine();
				
				if(line != null && line.contains("running")){
					UbuntuEnvironmentManager.getInstance().getEnvironment().getRunningServices().add(service);
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			//set parent package
			Iterator <InstalledPackage> pkgIter = UbuntuPackageManager.getInstance().getPkgMap().values().iterator();
			
			if(pkgIter != null){
				boolean found = false;
				
				while(pkgIter.hasNext() && !found){	
					InstalledPackage pkg = pkgIter.next();
					String pkgName = pkg.getName();
					
					if((serviceName.equals(pkgName)) || 
							(serviceName.contains(pkgName)) ||
									(pkgName.contains(serviceName))){
						
						UbuntuPackageManager.getInstance().getInstalledPackageByName(pkgName).getServices().add(service);
						
						found = true;
					}
				}
			}	
			
			setExecutable(service);
		}
		
	}
	
	protected void setExecutable(Service service){
		//TODO
	}

		@Override
		public void synchronize() throws IOException {
			createServicesFromSystem();
			
			int servicesInTheSystem = countServices();
			
			if(((this.serviceMap.size()) != servicesInTheSystem)){				
				Iterator<Service> iterator = this.serviceMap.values().iterator();
				while (iterator.hasNext()) {
					Service curr = iterator.next();
					if (isMissingServiceInTheSystem(curr.getName())) {
						this.serviceMap.remove(curr);
						EcoreUtil.delete(curr);
						UbuntuFileSystemManager.getInstance().deleteFile("/etc/init.d/" + curr.getName());
						//					UbuntuFileSystemManager.getInstance().deleteFile("/home/martina/prova/cartella/" + curr.getName());
					}
				}
			}
		}

		public int countServices() throws IOException {
			String line;
			int n = 0;
			try {
				String[] cmd = {"/bin/sh","-c","ls --time-style=long-iso /etc/init.d | wc | awk '{print $1}'"};
				
				BufferedReader input = ProcessCommand.getInstance().getResult(cmd);			
				
				line = input.readLine();
				
				n = Integer.parseInt (line);

			input.close();			
			
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			
			return n;
		}
		
		@Override
		public Boolean exists(String serviceName) {
			return this.serviceMap.containsKey(serviceName);
		}
		
		public boolean isMissingServiceInTheSystem (String serviceName) {
			if(UbuntuFileSystemManager.getInstance().getFile("/etc/init.d/" + serviceName) != null){
				return UbuntuFileSystemManager.getInstance().getFile("/etc/init.d/" + serviceName).isIsMissing();
			}else{
				return true;
			}
			
//			java.io.File file = new java.io.File("/etc/init.d/" + scriptName);
//			java.io.File file = new java.io.File("/home/martina/prova/cartella/" + scriptName);
//			return (file.exists());
		}

	}
